grpc::Status {{ name.upper_camel_case }}(
    grpc::ServerContext* /* context */,
    const rpc::{{ plugin_name.lower_snake_case }}::{{ name.upper_camel_case }}Request* {% if not params -%} /* request */ {%- else -%} request {%- endif -%},
    rpc::{{ plugin_name.lower_snake_case }}::{{ name.upper_camel_case }}Response* {% if has_result %}response{% else %}/* response */{% endif %}) override
{
    if (_lazy_plugin.maybe_plugin() == nullptr) {
        {% if has_result %}
        if (response != nullptr) {
            {% if is_server %}
            // For server plugins, this should never happen, they should always be constructible.
            auto result = mavsdk::{{ plugin_name.upper_camel_case }}::Result::Unknown;
            {% else -%}
            auto result = mavsdk::{{ plugin_name.upper_camel_case }}::Result::NoSystem;
            {% endif -%}
            fillResponseWithResult(response, result);
        }
        {% endif %}
        return grpc::Status::OK;
    }

    {% if params -%}
    if (request == nullptr) {
        LogWarn() << "{{ name.upper_camel_case }} sent with a null request! Ignoring...";
        return grpc::Status::OK;
    }
    {%- endif %}

    {%- for param in params %}
        {% if param.type_info.is_repeated %}
    std::vector<{{ package.lower_snake_case.split('.')[0] }}::{{ plugin_name.upper_camel_case }}::{{ param.type_info.inner_name }}> {{ param.name.lower_snake_case }}_vec;
    for (const auto& elem : request->{{ param.name.lower_snake_case }}()) {
        {{ param.name.lower_snake_case }}_vec.push_back({% if param.type_info.is_primitive %}elem{% else %}translateFromRpc{{ param.type_info.inner_name}}(elem){% endif %});
    }
        {% endif %}
    {% endfor -%}

    {% if is_sync %}
    {% if has_result %}auto result = {% endif %}_lazy_plugin.maybe_plugin()->{{ name.lower_snake_case }}({% for param in params %}{% if param.type_info.is_repeated %}{{ param.name.lower_snake_case }}_vec{% else %}{% if param.type_info.is_primitive %}request->{{ param.name.lower_snake_case }}(){% else %}translateFromRpc{{ param.type_info.inner_name }}(request->{{ param.name.lower_snake_case }}()){% endif %}{% endif %}{{ ", " if not loop.last }}{% endfor %});
    {% else %}
    std::promise<{% if has_result %}mavsdk::{{ plugin_name.upper_camel_case }}::Result{% else %}void{% endif %}> prom;
    std::future<{% if has_result %}mavsdk::{{ plugin_name.upper_camel_case }}::Result{% else %}void{% endif %}> fut = prom.get_future();

        {% if has_result %}
    _lazy_plugin.maybe_plugin()->{{ name.lower_snake_case }}_async([&prom](const mavsdk::{{ plugin_name.upper_camel_case }}::Result result){ prom.set_value(result); });
    auto result = fut.get();
        {% else %}
    _lazy_plugin.maybe_plugin()->{{ name.lower_snake_case }}_async([&prom](){ prom.set_value(); });
    fut.get();
        {% endif %}
    {% endif %}

    {% if has_result %}
    if (response != nullptr) {
        fillResponseWithResult(response, result);
    }
    {% endif %}

    return grpc::Status::OK;
}
